package com.cn.jm.util;

import com.alibaba.fastjson.JSONObject;
import com.cn.jm.core.pay.wechat.MD5Util;
import com.cn.jm.core.tool.JMToolString;
import com.jfinal.weixin.sdk.utils.HttpUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.tio.websocket.common.util.Md5;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author
 * @description 风控工具类
 * @date 2020/3/19
 */
public class RiskUtil {

    /**
     * 无界接口参数
     */
    private static final String PRODUCT = "";       //商户号
    private static final String KEY = "";           //私钥
    private static final String REQUEST_URL = "";   //无界运营商回调地址
    private static final String REDIRECT_URL = "";  //无界运营商回调地址

    /**
     * 风控接口参数
     */
    private static final String MODEL_NAME = "";    //模型号
    private static final String ITEM_PRODUCT = "";  //产品编号
    private static final String CHANNEL = "";       //渠道编号
    private static final String RISK_REQUEST_URL = "https://www.dazed.buzz/zhimi/risk/gzipV3";  //风控请求地址


    /**
     * 功能描述: 调用无界运营商接口
     * @author
     * @date 2020/3/19
     * @param phone
     * @param idcard
     * @param username
     * @param userId
     * @return void
     */
    public static String operatorV3Page(String phone, String idcard, String username, String userId, String page) throws UnsupportedEncodingException{
        //组装请求参数
        Map<String, String> map = new HashMap<>();
        map.put("phone", phone);
        map.put("idcard", idcard);
        map.put("product", PRODUCT);
        map.put("url", URLEncoder.encode(REDIRECT_URL, "utf-8"));//url编码
        if (JMToolString.isNotEmpty(page)) {
            map.put("page", URLEncoder.encode(page, "utf-8"));
        }
        map.put("sign", sign(phone, idcard, username));
        map.put("username", username);
        map.put("userId", userId);

        String url = REQUEST_URL + "?phone=" + phone + "&username=" + username + "&idcard=" + idcard + "&product=" + PRODUCT + "&url=" + map.get("url") + "&sign=" + map.get("sign");
        if (JMToolString.isNotEmpty(page)) {
            url += "&page=" + map.get("page");
        }
        url += "&userId=" + map.get("userId");
        System.out.println("无界运营商url：" + url);
        return url;
    }

    /**
     * 功能描述: 签名
     * @author
     * @date 2020/3/19
     * @param phone
     * @param idcard
     * @param username
     * @return java.lang.String
     */
    public static String sign(String phone, String idcard, String username){
        Map<String, Object> map = new HashMap<>();
        map.put("phone", phone);
        map.put("idcard", idcard);
        map.put("product", PRODUCT);
        map.put("key", KEY);
        map.put("username", username);

        String jsonString = JSONObject.toJSONString(map);
        String sign = MD5Util.MD5Encode(jsonString, null);
        return sign;
    }

    /**
     * 功能描述: 风控接口
     * @author
     * @date 2020/3/19
     * @param applyTime
    * @param mobile
    * @param name
    * @param idcard
    * @param phoneOs
    * @param EContactList
    * @param carrierData
    * @param contactList
     * @return java.lang.String
     */
    public static String riskGZip(String applyTime, String mobile, String name, String idcard, String phoneOs, List<Map> EContactList, Map<String, String> carrierData, List<Map> contactList) throws IOException{
        //组装请求参数
        Map<String, Object> map = new HashMap<>();
        map.put("model_name", MODEL_NAME);
        map.put("product", ITEM_PRODUCT);
        map.put("channel", CHANNEL);
        map.put("apply_time", applyTime);
        map.put("mobile", mobile);
        map.put("name", name);
        map.put("idcard", idcard);
        map.put("phone_os", phoneOs);
        map.put("e_contacts", EContactList);
        map.put("carrier_data", carrierData);
        map.put("contact", contactList);

        //压缩参数
        String jsonString = JSONObject.toJSONString(map);
//        System.out.println("jsonString = " + jsonString);
        byte[] gzipEncrypt = GZipUtil.compress(jsonString);

        CloseableHttpClient sslClientDefault = createSSLClientDefault();
        HttpPost post = new HttpPost(RISK_REQUEST_URL);
        post.setHeader("Content-Type", "application/json;charset=utf-8");
        post.setHeader("Accept", "application/json");
        post.setHeader("Content-Encoding", "gzip");
        post.setEntity(new InputStreamEntity(new ByteArrayInputStream(gzipEncrypt),gzipEncrypt.length));
        HttpResponse httpResponse = null;
        httpResponse = sslClientDefault.execute(post);
        HttpEntity response = httpResponse.getEntity();
        return  EntityUtils.toString(response);
    }

    public static CloseableHttpClient createSSLClientDefault() {
        try {
            //使用 loadTrustMaterial() 方法实现一个信任策略，信任所有证书
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                // 信任所有
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            //NoopHostnameVerifier类:  作为主机名验证工具，实质上关闭了主机名验证，它接受任何
            //有效的SSL会话并匹配到目标主机。
            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }
}
